﻿using Microsoft.VisualStudio.TestTools.UnitTesting;
using NTLib.Core.Garbadge;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace NTLib.Core.UTest.Garbadge
{
    [TestClass]
    public class GarbadgeUTest
    {
        #region Nested

        private class Counter
        {
            #region Fields

            private long i;

            #endregion

            #region Properties

            public long I
            {
                get
                {
                    return Interlocked.Read(ref i);
                }
            }

            #endregion

            #region Methods

            public void Increment()
            {
                Interlocked.Increment(ref i);
            }

            #endregion
        }

        #endregion

        #region Methods

        /// <summary>
        /// Garbadges the event call.
        /// </summary>
        [TestMethod]
        [TestCategory("Core.Garbadge")]
        public void GarbadgeEventCall()
        {
            Counter c = new Counter();

            Assert.IsFalse(GCHelper.IsRunning);

            GCHelper.GCEnded += c.Increment;

            Assert.IsTrue(GCHelper.IsRunning);

            CancellationTokenSource source = new CancellationTokenSource();

            Task.Run(async () =>
            {
                for (int i = 0; i < int.MaxValue; ++i)
                {
                    if (source.IsCancellationRequested)
                        return;
                    await Task.Delay(100);
                    GarbadgeUTest tst = new GarbadgeUTest();
                    Debug.WriteLine(tst.GetHashCode());

                    if (i % 100 == 0)
                        GC.Collect();
                }
            });

            Task.Delay(1000 * 130).Wait();
            source.Cancel();
            Assert.IsTrue(c.I > 5);

            GCHelper.GCEnded -= c.Increment;

            Assert.IsFalse(GCHelper.IsRunning);
        }

        #endregion
    }
}
